#include <sys/mman.h> // mmap, munmap, PROT_READ, PROT_WRITE, MAP_SHARED, MAP_FAILED
#include <fcntl.h> // shm_open
#include <unistd.h>
#include <sys/stat.h>// 包含 sleep 函数
#include <string>
#include <iostream>
#include <sstream>
#include <cstdlib>  // 包含 std::atoi 函数
#include <memory>  // std::shared_ptr
#include <cstring>  // memcpy

// 模拟 INFO 宏的定义
#define INFO "INFO"
#define ERROR "ERROR"
#define LOG(level) std::cerr << "[" << CURRENT_TIME << "] : "

#include <iomanip>
#include <chrono>
#include <ctime>
#include <sstream>
// 定义一个宏来获取当前时间并格式化，包含毫秒
#define CURRENT_TIME \
    ([]() -> std::string { \
        auto now = std::chrono::system_clock::now(); \
        auto now_c = std::chrono::system_clock::to_time_t(now); \
        auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000; \
        std::tm tm = *std::localtime(&now_c); \
        std::ostringstream oss; \
        oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S") << '.' << std::setfill('0') << std::setw(3) << milliseconds.count(); \
        return oss.str(); \
    }())


#define IN
#define OUT
    auto OpenSharedMemory = [](std::shared_ptr<int> OUT fd, const IN std::string & shared_mem_name) -> bool 
    {
        // 尝试打开共享内存对象
        *fd = shm_open(shared_mem_name.c_str(), O_RDWR, 0666);
        if (*fd == -1) {
            LOG(INFO) << "CheckFailedSystemRunStat : OpenSharedMemory failed" << std::endl;
            // perror("shm_open");
            return false; // 返回错误码以便调用者处理
        }
        return true;
    };

    auto GetSharedMemoryObjectSize = [](const std::shared_ptr<int> IN fd, std::shared_ptr<off_t> OUT memSize) -> bool 
    {
        // 读取共享内存大小
        struct stat sb;
        if (fstat(*fd, &sb) == -1) {
            // perror("fstat");
            // exit(EXIT_FAILURE);
            LOG(ERROR) << "GetSharedMemoryObjectSize : get fstat failed" << std::endl;
            return false;
        }
        else
        {
            *memSize = sb.st_size;
        }
        return true;
    };

    auto CreateSharedMemory = [](std::shared_ptr<int> OUT fd , const std::string IN & shared_mem_name) -> bool 
    {
        // 创建并打开共享内存对象
        *fd = shm_open(shared_mem_name.c_str(), O_CREAT | O_RDWR | O_EXCL, 0666);
        // O_RDONLY: 以只读方式打开共享内存对象。
        // O_RDWR: 以读写方式打开共享内存对象。
        // O_CREAT: 如果共享内存对象不存在，则创建它。
        // O_EXCL: 如果指定了 O_CREAT 并且共享内存对象已经存在，则返回错误。
        // O_TRUNC: 如果共享内存对象已经存在，并且以可写方式打开，则将其长度截断为0
        // 0666: 共享内存对象的权限（八进制），表示所有用户可读写。
        if(*fd == -1)
        {
            if(errno == EEXIST)
            {
                shm_unlink(shared_mem_name.c_str());
            }
            LOG(ERROR) << "CreateSharedMemory : shm_open failed" << std::endl;
            return false;
            // perror("shm_open");
            // exit(EXIT_FAILURE);
        }
        return true;
    };
    auto SetSharedMemoryObjectSize = [](const std::shared_ptr<int> IN fd , off_t IN mem_size,  const std::string IN & shared_mem_name) -> bool
    {
        // 设置共享内存对象的大小
        if (ftruncate(*fd, mem_size) == -1) {
            shm_unlink(shared_mem_name.c_str());
            LOG(ERROR) << "SetSharedMemoryObjectSize : ftruncate failed" << std::endl;
            // perror("ftruncate");
            // exit(EXIT_FAILURE);
            return false;
        }
        return true;
    };
    auto MappingSharedMemoryObjects = [](const std::shared_ptr<int> IN fd , off_t IN mem_size,  const std::string IN & shared_mem_name, void ** OUT ptr) -> bool
    {
        // 映射共享内存对象
        *ptr = mmap(NULL, mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
        if (*ptr == MAP_FAILED) {
            LOG(ERROR) << "MappingSharedMemoryObjects : mmap failed" << std::endl;
            // perror("mmap");
            shm_unlink(shared_mem_name.c_str());
            // exit(EXIT_FAILURE);
            return false;
        }
        return true;
    };
#undef IN
#undef OUT

// 检查是否异常重启
bool CreateSHM(const std::string & mem_name, off_t mem_size)
{
    std::shared_ptr<int> fd(new int);

    if (CreateSharedMemory(fd,mem_name)) // 共享内存已经存在
    {
        if (!SetSharedMemoryObjectSize(fd, mem_size, mem_name)) //如果获取不到内存空间大小或者大小错误
        {
            return false;
        }
        else // 如果都是正常的
        {
            void * ptr;
            if (!MappingSharedMemoryObjects(fd, mem_size, mem_name, &ptr))
            {
                // shm_unlink(mem_name.c_str()); // 已经删除空间，无需删除
            }
            else
            {
                // 假设已经知道共享内存的数据，读取共享内存的内容
                int stat = 0x11223344;
                memcpy(ptr, &stat, sizeof(int));  // 使用 memcpy 将值写入共享内存
                close(*fd);
                return true;
            }
        }
    }
    close(*fd);
    return false;
}

int main(int argc, char* argv[]) {
    std::string mem_name = "/TankControlStat";
    int mem_size = 4;
    float period = 3;
    
    if (argc == 1)
    {
        // std::string mem_name = argv[0];
    }
    else
    if (argc != 4 && argc != 1) {
        std::cerr << "Usage: " << argv[0] << " <shm name> <memSize> <print period>" << std::endl;
        std::cerr << "\t example :" << argv[0] << " /ControlStat 4 0.2" << std::endl;
        return 1;
    }
    else
    {
        try
        {
            mem_name = argv[1];
            mem_size = std::atoi(argv[2]);
            period = std::atof(argv[2]);
        }
        catch(const std::exception& e)
        {
            std::cerr << e.what() << '\n';
            return 1;
        }
        
    }

    CreateSHM(mem_name, mem_size);
    // sleep(period);  // 暂停指定的秒数

    

    return 0;
}